home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / AMScen_0_9.lha / AMScen / graphics.m < prev    next >
Text File  |  1995-01-21  |  43KB  |  1,750 lines

  1. /*
  2.  * Amiga MUD
  3.  *
  4.  * Copyright (c) 1995 by Chris Gray
  5.  */
  6.  
  7. /*
  8.  * graphics.m - some stuff to do simple graphics.
  9.  */
  10.  
  11. private tp_graphics CreateTable().
  12. use tp_graphics
  13.  
  14. define t_graphics p_rName1 CreateStringProp().
  15. define t_graphics p_rName2 CreateStringProp().
  16. define t_graphics p_rBackGroundPen CreateIntProp().
  17. define t_graphics p_rForeGroundPen CreateIntProp().
  18. define t_graphics p_rEdgePen CreateIntProp().
  19. define t_graphics p_rDoorPen CreateIntProp().
  20. define t_graphics p_rCursorX CreateIntProp().
  21. define t_graphics p_rCursorY CreateIntProp().
  22. define t_graphics p_rDrawAction CreateActionProp().
  23. define t_graphics p_pStandardButtonsNow CreateBoolProp().
  24.  
  25. define tp_graphics p_rAutoGraphics CreateBoolProp().
  26. define tp_graphics p_rAutoDrawAction CreateActionProp().
  27.  
  28. /* first, some names for the standard colours */
  29.  
  30. define t_graphics C_BLACK        0.
  31. define t_graphics C_DARK_GREY        1.
  32. define t_graphics C_MEDIUM_GREY     2.
  33. define t_graphics C_LIGHT_GREY        3.
  34. define t_graphics C_WHITE        4.
  35. define t_graphics C_BRICK_RED        5.
  36. define t_graphics C_RED         6.
  37. define t_graphics C_RED_ORANGE        7.
  38. define t_graphics C_ORANGE        8.
  39. define t_graphics C_GOLD        9.
  40. define t_graphics C_CADMIUM_YELLOW 10.
  41. define t_graphics C_LEMON_YELLOW   11.
  42. define t_graphics C_LIME_GREEN       12.
  43. define t_graphics C_GREEN       13.
  44. define t_graphics C_LIGHT_GREEN    14.
  45. define t_graphics C_DARK_GREEN       15.
  46. define t_graphics C_FOREST_GREEN   16.
  47. define t_graphics C_BLUE_GREEN       17.
  48. define t_graphics C_AQUA       18.
  49. define t_graphics C_LIGHT_AQUA       19.
  50. define t_graphics C_SKY_BLUE       20.
  51. define t_graphics C_LIGHT_BLUE       21.
  52. define t_graphics C_BLUE       22.
  53. define t_graphics C_DARK_BLUE       23.
  54. define t_graphics C_VIOLET       24.
  55. define t_graphics C_PURPLE       25.
  56. define t_graphics C_MAGENTA       26.
  57. define t_graphics C_PINK       27.
  58. define t_graphics C_TAN        28.
  59. define t_graphics C_BROWN       29.
  60. define t_graphics C_MEDIUM_BROWN   30.
  61. define t_graphics C_DARK_BROWN       31.
  62.  
  63. /*
  64.  * ColourMatch - a routine to map name to number at run-time
  65.  */
  66.  
  67. define t_graphics proc public ColourMatch(string name)int:
  68.  
  69.     if name == "grey" then
  70.     C_MEDIUM_GREY
  71.     elif name == "red" then
  72.     C_RED
  73.     elif name == "green" then
  74.     C_GREEN
  75.     elif name == "blue" then
  76.     C_BLUE
  77.     else
  78.     MatchName(
  79.         "black.grey;dark.grey;medium.grey;light.white.red;brick.red."
  80.         "red-orange.orange.gold.yellow;cadmium.yellow;lemon.green;lime."
  81.         "green.green;light.green;dark.green;forest.blue-green.aqua."
  82.         "aqua;light.blue;sky.blue;light.blue.blue;dark.violet.purple."
  83.         "magenta.pink.tan.brown.brown;medium.brown;dark", name)
  84.     fi
  85. corp;
  86.  
  87. /*
  88.  * ColourName - map from colour number to colour name
  89.  */
  90.  
  91. define t_graphics proc public ColourName(int colour)string:
  92.  
  93.     case colour
  94.     incase C_BLACK:        "black"
  95.     incase C_DARK_GREY:     "dark grey"
  96.     incase C_MEDIUM_GREY:    "medium grey"
  97.     incase C_LIGHT_GREY:    "light grey"
  98.     incase C_WHITE:        "white"
  99.     incase C_BRICK_RED:     "brick red"
  100.     incase C_RED:        "red"
  101.     incase C_RED_ORANGE:    "red-orange"
  102.     incase C_ORANGE:        "orange"
  103.     incase C_GOLD:        "gold"
  104.     incase C_CADMIUM_YELLOW:    "cadmium yellow"
  105.     incase C_LEMON_YELLOW:    "lemon yellow"
  106.     incase C_LIME_GREEN:    "lime green"
  107.     incase C_GREEN:        "green"
  108.     incase C_LIGHT_GREEN:    "light green"
  109.     incase C_DARK_GREEN:    "dark green"
  110.     incase C_FOREST_GREEN:    "forest green"
  111.     incase C_BLUE_GREEN:    "blue green"
  112.     incase C_AQUA:        "aqua"
  113.     incase C_LIGHT_AQUA:    "light aqua"
  114.     incase C_SKY_BLUE:        "sky blue"
  115.     incase C_LIGHT_BLUE:    "light blue"
  116.     incase C_BLUE:        "blue"
  117.     incase C_DARK_BLUE:     "dark blue"
  118.     incase C_VIOLET:        "violet"
  119.     incase C_PURPLE:        "purple"
  120.     incase C_MAGENTA:        "magenta"
  121.     incase C_PINK:        "pink"
  122.     incase C_TAN:        "tan"
  123.     incase C_BROWN:        "brown"
  124.     incase C_MEDIUM_BROWN:    "medium brown"
  125.     incase C_DARK_BROWN:    "dark brown"
  126.     default:            "<BAD-COLOUR>"
  127.     esac
  128. corp;
  129.  
  130. /*
  131.  * ShowKnownColours - print the colour names that we understand.
  132.  */
  133.  
  134. define t_graphics proc public ShowKnownColours()void:
  135.  
  136.     Print("Known colours are: "
  137.     "black, "
  138.     "dark grey, "
  139.     "medium grey, "
  140.     "light grey, "
  141.     "white, "
  142.     "brick red, "
  143.     "red, "
  144.     "red-orange, "
  145.     "orange, "
  146.     "gold, "
  147.     "cadmium yellow, "
  148.     "lemon yellow, "
  149.     "lime green, "
  150.     "green, "
  151.     "light green, "
  152.     "dark green, "
  153.     "forest green, "
  154.     "green-blue, "
  155.     "aqua, "
  156.     "light aqua, "
  157.     "sky blue, "
  158.     "light blue, "
  159.     "blue, "
  160.     "dark blue, "
  161.     "violet, "
  162.     "purple, "
  163.     "magenta, "
  164.     "pink, "
  165.     "tan, "
  166.     "brown, "
  167.     "medium brown, "
  168.     "dark brown\n"
  169.     );
  170. corp;
  171.  
  172. /* tools for providing unique map group and effect id values */
  173.  
  174. /* some standard MapGroup values */
  175.  
  176. define t_graphics UNKNOWN_MAP_GROUP    -1.
  177. define t_graphics NO_MAP_GROUP        0.
  178. define t_graphics AUTO_MAP_GROUP    1.
  179.  
  180. define tp_graphics GraphicsThing CreateThing(nil).
  181. define tp_graphics p_NextMapGroup CreateIntProp().
  182. define tp_graphics p_NextEffectId CreateIntProp().
  183. GraphicsThing@p_NextMapGroup := AUTO_MAP_GROUP + 1.
  184. GraphicsThing@p_NextEffectId := 1.
  185.  
  186. define t_graphics proc public NextMapGroup()int:
  187.     int g;
  188.  
  189.     g := GraphicsThing@p_NextMapGroup;
  190.     GraphicsThing@p_NextMapGroup := g + 1;
  191.     g
  192. corp;
  193.  
  194. define t_graphics proc public NextEffectId()int:
  195.     int id;
  196.  
  197.     id := GraphicsThing@p_NextEffectId;
  198.     GraphicsThing@p_NextEffectId := id + 1;
  199.     id
  200. corp;
  201.  
  202. /* next, some general titling stuff */
  203.  
  204. define tp_graphics ROOM_NAME_BOX_ID NextEffectId().
  205.  
  206. define t_graphics proc public DrawRoomNameBox()void:
  207.     int i;
  208.  
  209.     if not KnowsEffect(nil, ROOM_NAME_BOX_ID) then
  210.     DefineEffect(nil, ROOM_NAME_BOX_ID);
  211.     for i from 0 upto 3 do
  212.         GSetPen(nil, i + 1);
  213.         GAMove(nil, 162 + i, i);
  214.         GRectangle(nil, 155 - 2 * i, 29 - 2 * i, false);
  215.     od;
  216.     EndEffect();
  217.     fi;
  218.     CallEffect(nil, ROOM_NAME_BOX_ID);
  219. corp;
  220.  
  221. define t_graphics proc public DrawRoomName(string s1, s2)void:
  222.     int len;
  223.  
  224.     GSetPen(nil, C_BLACK);
  225.     GAMove(nil, 168, 6);
  226.     GRectangle(nil, 143, 17, true);
  227.     GSetPen(nil, C_GOLD);
  228.     len := Length(s2);
  229.     if len ~= 0 then
  230.     if len > 18 then
  231.         len := 18;
  232.         s2 := SubString(s2, 0, 18);
  233.     fi;
  234.     GAMove(nil, 240 - len * 4, 22);
  235.     GText(nil, s2);
  236.     len := Length(s1);
  237.     if len > 18 then
  238.         len := 18;
  239.         s1 := SubString(s1, 0, 18);
  240.     fi;
  241.     GAMove(nil, 240 - len * 4, 12);
  242.     GText(nil, s1);
  243.     else
  244.     len := Length(s1);
  245.     if len > 18 then
  246.         len := 18;
  247.         s1 := SubString(s1, 0, 18);
  248.     fi;
  249.     GAMove(nil, 240 - len * 4, 17);
  250.     GText(nil, s1);
  251.     fi;
  252. corp;
  253.  
  254. define tp_graphics HORIZONTAL_DOOR_ID NextEffectId().
  255. define tp_graphics VERTICAL_DOOR_ID NextEffectId().
  256. define tp_graphics NORTHWEST_DOOR_ID NextEffectId().
  257. define tp_graphics NORTHEAST_DOOR_ID NextEffectId().
  258.  
  259. define t_graphics proc public HorizontalDoor()void:
  260.  
  261.     if not KnowsEffect(nil, HORIZONTAL_DOOR_ID) then
  262.     DefineEffect(nil, HORIZONTAL_DOOR_ID);
  263.     GRMove(nil, 0, -1);
  264.     GRDraw(nil, 0, 2);
  265.     GRMove(nil, 0, -1);
  266.     GRDraw(nil, 10, 0);
  267.     GRMove(nil, 0, -1);
  268.     GRDraw(nil, 0, 2);
  269.     EndEffect();
  270.     fi;
  271.     CallEffect(nil, HORIZONTAL_DOOR_ID);
  272. corp;
  273.  
  274. define t_graphics proc public VerticalDoor()void:
  275.  
  276.     if not KnowsEffect(nil, VERTICAL_DOOR_ID) then
  277.     DefineEffect(nil, VERTICAL_DOOR_ID);
  278.     GRMove(nil, -1, 0);
  279.     GRDraw(nil, 2, 0);
  280.     GRMove(nil, -1, 0);
  281.     GRDraw(nil, 0, 8);
  282.     GRMove(nil, -1, 0);
  283.     GRDraw(nil, 2, 0);
  284.     EndEffect();
  285.     fi;
  286.     CallEffect(nil, VERTICAL_DOOR_ID);
  287. corp;
  288.  
  289. define t_graphics proc public NorthWestDoor()void:
  290.  
  291.     if not KnowsEffect(nil, NORTHWEST_DOOR_ID) then
  292.     DefineEffect(nil, NORTHWEST_DOOR_ID);
  293.     GRMove(nil, -1, -1);
  294.     GRDraw(nil, 2, 2);
  295.     GRMove(nil, -1, -1);
  296.     GRDraw(nil, -4, 4);
  297.     GRMove(nil, -1, -1);
  298.     GRDraw(nil, 2, 2);
  299.     EndEffect();
  300.     fi;
  301.     CallEffect(nil, NORTHWEST_DOOR_ID);
  302. corp;
  303.  
  304. define t_graphics proc public NorthEastDoor()void:
  305.  
  306.     if not KnowsEffect(nil, NORTHEAST_DOOR_ID) then
  307.     DefineEffect(nil, NORTHEAST_DOOR_ID);
  308.     GRMove(nil, 1, -1);
  309.     GRDraw(nil, -2, 2);
  310.     GRMove(nil, 1, -1);
  311.     GRDraw(nil, 4, 4);
  312.     GRMove(nil, 1, -1);
  313.     GRDraw(nil, -2, 2);
  314.     EndEffect();
  315.     fi;
  316.     CallEffect(nil, NORTHEAST_DOOR_ID);
  317. corp;
  318.  
  319. /* a proc to yield the standard cursor for a character */
  320.  
  321. define t_graphics proc public MakeCursor()list int:
  322.     list int li;
  323.  
  324.     li := CreateIntArray(8);
  325.     li[0] := 0b01111100000000001100011000000000;
  326.     li[1] := 0b10101010000000001000001000000000;
  327.     li[2] := 0b10111010000000001100011000000000;
  328.     li[3] := 0b01111100000000000000000000000000;
  329.     li[4] := 0b00000000000000000000000000000000;
  330.     li[5] := 0b00000000000000000000000000000000;
  331.     li[6] := 0b00000000000000000000000000000000;
  332.     li[7] := 0b00000000000000000000000000000000;
  333.     li
  334. corp;
  335.  
  336. /* proc that can be attached to things, and which zaps all buttons. */
  337. /* We need this since we cannot attach builtins to things. */
  338.  
  339. define t_graphics proc EraseAllButtons()void:
  340.  
  341.     ClearButtons();
  342. corp;
  343.  
  344. /* create the standard set of movement buttons and region */
  345.  
  346. define t_graphics NW_BUTTON    1.
  347. define t_graphics N_BUTTON    2.
  348. define t_graphics NE_BUTTON    3.
  349. define t_graphics W_BUTTON    4.
  350. define t_graphics L_BUTTON    5.
  351. define t_graphics E_BUTTON    6.
  352. define t_graphics SW_BUTTON    7.
  353. define t_graphics S_BUTTON    8.
  354. define t_graphics SE_BUTTON    9.
  355. define t_graphics D_BUTTON    10.
  356. define t_graphics U_BUTTON    11.
  357. define t_graphics I_BUTTON    12.
  358. define t_graphics O_BUTTON    13.
  359. define t_graphics MOVE_REGION    1000.    /* want it large, so others override */
  360.  
  361. define tp_graphics ADD_DIRECTION_BUTTONS_ID NextEffectId().
  362. define tp_graphics ERASE_DIRECTION_BUTTONS_ID NextEffectId().
  363.  
  364. define t_graphics proc public AddDirectionButtons()void:
  365.  
  366.     if not KnowsEffect(nil, ADD_DIRECTION_BUTTONS_ID) then
  367.     DefineEffect(nil, ADD_DIRECTION_BUTTONS_ID);
  368.     AddButton(206, 31, NW_BUTTON, "NW");
  369.     AddButton(231, 31, N_BUTTON, "N");
  370.     AddButton(248, 31, NE_BUTTON, "NE");
  371.     AddButton(210, 48, W_BUTTON, "W");
  372.     AddButton(252, 48, E_BUTTON, "E");
  373.     AddButton(206, 65, SW_BUTTON, "SW");
  374.     AddButton(231, 65, S_BUTTON, "S");
  375.     AddButton(248, 65, SE_BUTTON, "SE");
  376.     AddButton(273, 39, U_BUTTON, "U");
  377.     AddButton(273, 57, D_BUTTON, "D");
  378.     AddButton(189, 39, I_BUTTON, "I");
  379.     AddButton(189, 57, O_BUTTON, "O");
  380.     EndEffect();
  381.     fi;
  382.     CallEffect(nil, ADD_DIRECTION_BUTTONS_ID);
  383. corp;
  384.  
  385. define t_graphics proc public EraseDirectionButtons()void:
  386.  
  387.     if not KnowsEffect(nil, ERASE_DIRECTION_BUTTONS_ID) then
  388.     DefineEffect(nil, ERASE_DIRECTION_BUTTONS_ID);
  389.     EraseButton(NW_BUTTON);
  390.     EraseButton(N_BUTTON);
  391.     EraseButton(NE_BUTTON);
  392.     EraseButton(W_BUTTON);
  393.     EraseButton(E_BUTTON);
  394.     EraseButton(SW_BUTTON);
  395.     EraseButton(S_BUTTON);
  396.     EraseButton(SE_BUTTON);
  397.     EraseButton(U_BUTTON);
  398.     EraseButton(D_BUTTON);
  399.     EraseButton(I_BUTTON);
  400.     EraseButton(O_BUTTON);
  401.     EndEffect();
  402.     fi;
  403.     CallEffect(nil, ERASE_DIRECTION_BUTTONS_ID);
  404. corp;
  405.  
  406. define t_graphics proc public AddStandardButtons()void:
  407.  
  408.     AddDirectionButtons();
  409.     AddButton(231, 48, L_BUTTON, "L");
  410.     Me()@p_pStandardButtonsNow := true;
  411. corp;
  412.  
  413. define t_graphics proc public AddStandardRegions()void:
  414.  
  415.     AddRegion(0, 0, 159, 99, MOVE_REGION);
  416. corp;
  417.  
  418. define t_graphics proc public EraseStandardButtons()void:
  419.  
  420.     EraseDirectionButtons();
  421.     EraseButton(L_BUTTON);
  422. corp;
  423.  
  424. define t_graphics proc public EraseStandardRegions()void:
  425.  
  426.     EraseRegion(MOVE_REGION);
  427. corp;
  428.  
  429. /* a standard button handler for the above buttons */
  430.  
  431. define t_graphics proc public StandardButtonHandler(int whichButton)void:
  432.  
  433.     case whichButton
  434.     incase NW_BUTTON:
  435.     InsertCommand("northwest");
  436.     incase N_BUTTON:
  437.     InsertCommand("north");
  438.     incase NE_BUTTON:
  439.     InsertCommand("northeast");
  440.     incase W_BUTTON:
  441.     InsertCommand("west");
  442.     incase L_BUTTON:
  443.     InsertCommand("look");
  444.     incase E_BUTTON:
  445.     InsertCommand("east");
  446.     incase SW_BUTTON:
  447.     InsertCommand("southwest");
  448.     incase S_BUTTON:
  449.     InsertCommand("south");
  450.     incase SE_BUTTON:
  451.     InsertCommand("southeast");
  452.     incase U_BUTTON:
  453.     InsertCommand("up");
  454.     incase D_BUTTON:
  455.     InsertCommand("down");
  456.     incase I_BUTTON:
  457.     InsertCommand("in");
  458.     incase O_BUTTON:
  459.     InsertCommand("out");
  460.     default:
  461.     Print("Unknown button ");
  462.     IPrint(whichButton);
  463.     Print(" hit!\n");
  464.     esac;
  465. corp;
  466.  
  467. /* a standard region hit handler for the above region */
  468.  
  469. define t_graphics proc public StandardMouseDownHandler(int region, x, y)void:
  470.     thing here;
  471.     int cursorX, cursorY, deltaX, deltaY;
  472.  
  473.     if region = MOVE_REGION then
  474.     here := Here();
  475.     cursorX := here@p_rCursorX;
  476.     cursorY := here@p_rCursorY;
  477.     if cursorX = 0 and cursorY = 0 and here@p_rAutoGraphics then
  478.         /* pick the middle of the mapping region */
  479.         cursorX := 80;
  480.         cursorY := 50;
  481.     else
  482.         /* adjust to center of 7 x 7 cursor pattern */
  483.         cursorX := cursorX + 3;
  484.         cursorY := cursorY + 3;
  485.     fi;
  486.     if cursorX < x then
  487.         deltaX := x - cursorX;
  488.     else
  489.         deltaX := cursorX - x;
  490.     fi;
  491.     if cursorY < y then
  492.         deltaY := y - cursorY;
  493.     else
  494.         deltaY := cursorY - y;
  495.     fi;
  496.     if deltaY * 10 <= deltaX * 4 then
  497.         if x < cursorX then
  498.         InsertCommand("west");
  499.         else
  500.         InsertCommand("east");
  501.         fi;
  502.     elif deltaX * 10 <= deltaY * 4 then
  503.         if y < cursorY then
  504.         InsertCommand("north");
  505.         else
  506.         InsertCommand("south");
  507.         fi;
  508.     else
  509.         if x < cursorX then
  510.         if y < cursorY then
  511.             InsertCommand("northwest");
  512.         else
  513.             InsertCommand("southwest");
  514.         fi;
  515.         else
  516.         if y < cursorY then
  517.             InsertCommand("northeast");
  518.         else
  519.             InsertCommand("southeast");
  520.         fi;
  521.         fi;
  522.     fi;
  523.     else
  524.     Print("Unknown region ");
  525.     IPrint(region);
  526.     Print(" hit!\n");
  527.     fi;
  528. corp;
  529.  
  530. /* set up the standard graphics stuff. */
  531.  
  532. define t_graphics p_pStandardGraphicsDone CreateBoolProp().
  533.  
  534. define t_graphics proc public InitStandardGraphics()void:
  535.     thing me;
  536.  
  537.     me := Me();
  538.     GClear(nil);
  539.     DrawRoomNameBox();
  540.     AddStandardButtons();
  541.     AddStandardRegions();
  542.     SetCursorPen(me@p_pCursorColour);
  543.     SetCursorPattern(me@p_pCursor);
  544.     GSetIconPen(nil, me@p_pIconColour);
  545.     me@p_pStandardGraphicsDone := true;
  546. corp;
  547.  
  548. define tp_graphics CLEAR_GRAPHICS_ID NextEffectId().
  549. define t_graphics proc public ClearGraphics()void:
  550.  
  551.     if not KnowsEffect(nil, CLEAR_GRAPHICS_ID) then
  552.     DefineEffect(nil, CLEAR_GRAPHICS_ID);
  553.     GSetPen(nil, C_BLACK);
  554.     GAMove(nil, 0, 0);
  555.     GRectangle(nil, 159, 99, true);
  556.     EndEffect();
  557.     fi;
  558.     CallEffect(nil, CLEAR_GRAPHICS_ID);
  559. corp;
  560.  
  561. /* these are used when entering and exiting a room using this scheme. */
  562.  
  563. define t_graphics proc public EnterRoomDraw()void:
  564.     thing me, here;
  565.     int g, len, pos;
  566.     string name;
  567.     action a;
  568.  
  569.     me := Me();
  570.     here := Here();
  571.     g := me@p_MapGroup;
  572.     if here@p_rAutoGraphics and here@p_rDrawAction = nil then
  573.     if g ~= AUTO_MAP_GROUP then
  574.         if not me@p_pStandardGraphicsDone then
  575.         InitStandardGraphics();
  576.         else
  577.         ClearGraphics();
  578.         fi;
  579.         me@p_MapGroup := AUTO_MAP_GROUP;
  580.     fi;
  581.     a := here@p_rAutoDrawAction;
  582.     if a ~= nil then
  583.         call(a, void)();
  584.     fi;
  585.     if here@p_rName1 ~= "" then
  586.         DrawRoomName(here@p_rName1, here@p_rName2);
  587.     else
  588.         name := here@p_rName;
  589.         len := Length(name);
  590.         pos := len - 1;
  591.         while pos ~= 0 and SubString(name, pos, 1) ~= " " do
  592.         pos := pos - 1;
  593.         od;
  594.         if SubString(name, pos, 1) = " " then
  595.         pos := pos + 1;
  596.         fi;
  597.         DrawRoomName(Capitalize(SubString(name, pos, len - pos)), "");
  598.     fi;
  599.     PlaceCursor(77, 47);
  600.     else
  601.     if g = NO_MAP_GROUP then
  602.         /* The place the character was previously at did not use room
  603.            graphics, so start it up */
  604.         if not me@p_pStandardGraphicsDone then
  605.         InitStandardGraphics();
  606.         else
  607.         ClearGraphics();
  608.         fi;
  609.     fi;
  610.     if g ~= here@p_MapGroup then
  611.         /* The current room (the character has just entered it, or is doing
  612.            a 'look'), uses room graphics, and the map group for the room
  613.            is different from that which was last shown to the player.
  614.            Remember the new group in the player, clear the room graphics
  615.            area, and call the room's display function. */
  616.         me@p_MapGroup := here@p_MapGroup;
  617.         ClearGraphics();
  618.         a := here@p_rDrawAction;
  619.         if a ~= nil then
  620.         call(a, void)();
  621.         fi;
  622.     fi;
  623.     DrawRoomName(here@p_rName1, here@p_rName2);
  624.     if here@p_rCursorX ~= 0 or here@p_rCursorY ~= 0 then
  625.         PlaceCursor(here@p_rCursorX, here@p_rCursorY);
  626.     fi;
  627.     fi;
  628. corp;
  629.  
  630. define t_graphics proc public LeaveRoomDraw(thing dest)void:
  631.  
  632.     RemoveCursor();
  633.     if dest = nil or dest@p_rEnterRoomDraw = nil then
  634.     /* No room graphics in destination - clear the display area, etc. */
  635.     ClearGraphics();
  636.     DrawRoomName("", "");
  637.     Me()@p_MapGroup := NO_MAP_GROUP;
  638.     fi;
  639. corp;
  640.  
  641. /*
  642.  * RoomGraphics - set up a room for standard form custom graphics.
  643.  */
  644.  
  645. define t_graphics proc public RoomGraphics(thing room; string name1, name2;
  646.     int group, x, y; action drawAction)void:
  647.  
  648.     room -- p_rAutoGraphics;
  649.     if name1 ~= "" then
  650.     room@p_rName1 := name1;
  651.     fi;
  652.     if name2 ~= "" then
  653.     room@p_rName2 := name2;
  654.     fi;
  655.     room@p_MapGroup := group;
  656.     if x ~= 0 then
  657.     room@p_rCursorX := x;
  658.     fi;
  659.     if y ~= 0 then
  660.     room@p_rCursorY := y;
  661.     fi;
  662.     if drawAction ~= nil then
  663.     room@p_rDrawAction := drawAction;
  664.     fi;
  665.     room@p_rEnterRoomDraw := EnterRoomDraw;
  666.     room@p_rLeaveRoomDraw := LeaveRoomDraw;
  667. corp;
  668.  
  669. /* the following few are 'utility' so they can be used in build code */
  670.  
  671. /*
  672.  * AutoGraphics - set up a room to use auto graphics.
  673.  */
  674.  
  675. define t_graphics proc utility AutoGraphics(thing room; action drawAction)void:
  676.  
  677.     room@p_rAutoGraphics := true;
  678.     room@p_rEnterRoomDraw := EnterRoomDraw;
  679.     room@p_rLeaveRoomDraw := LeaveRoomDraw;
  680.     room@p_rAutoDrawAction := drawAction;
  681. corp;
  682.  
  683. /*
  684.  * AutoRedraw - redraw the room for the current user.
  685.  */
  686.  
  687. define t_graphics proc utility AutoRedraw()void:
  688.     action a;
  689.  
  690.     if Here()@p_rDrawAction = nil then
  691.     a := Here()@p_rAutoDrawAction;
  692.     if a ~= nil then
  693.         GUndrawIcons(nil);
  694.         RemoveCursor();
  695.         call(a, void)();
  696.         PlaceCursor(77, 47);
  697.         GRedrawIcons(nil);
  698.     fi;
  699.     fi;
  700. corp;
  701.  
  702. /*
  703.  * AutoPens - set the pens for auto graphics.
  704.  */
  705.  
  706. define t_graphics proc utility AutoPens(thing room;
  707.     int back, fore, edge, door)void:
  708.  
  709.     if back ~= 0 then
  710.     room@p_rBackGroundPen := back;
  711.     else
  712.     room -- p_rBackGroundPen;
  713.     fi;
  714.     if fore ~= 0 then
  715.     room@p_rForeGroundPen := fore;
  716.     else
  717.     room -- p_rForeGroundPen;
  718.     fi;
  719.     if edge ~= 0 then
  720.     room@p_rEdgePen := edge;
  721.     else
  722.     room -- p_rEdgePen;
  723.     fi;
  724.     if door ~= 0 then
  725.     room@p_rDoorPen := door;
  726.     else
  727.     room -- p_rDoorPen;
  728.     fi;
  729. corp;
  730.  
  731. /*
  732.  * RoomName - set the graphics name of the room.
  733.  */
  734.  
  735. define t_graphics proc utility RoomName(thing room; string name1, name2)void:
  736.  
  737.     room@p_rName1 := name1;
  738.     if name2 ~= "" then
  739.     room@p_rName2 := name2;
  740.     else
  741.     room -- p_rName2;
  742.     fi;
  743. corp;
  744.  
  745. define tp_graphics GOLD_UP_ARROW_ID NextEffectId().
  746. define tp_graphics GOLD_DOWN_ARROW_ID NextEffectId().
  747.  
  748. /*
  749.  * DrawUpArrow - draw the up arrow.
  750.  */
  751.  
  752. define t_graphics proc DrawUpArrow(int pen)void:
  753.  
  754.     if pen = C_GOLD then
  755.     if not KnowsEffect(nil, GOLD_UP_ARROW_ID) then
  756.         DefineEffect(nil, GOLD_UP_ARROW_ID);
  757.         GSetPen(nil, C_GOLD);
  758.         GAMove(nil, 86, 45);
  759.         GRDraw(nil, 5, -5);
  760.         GRDraw(nil, 5, 5);
  761.         GRMove(nil, -5, -5);
  762.         GRDraw(nil, 0, 20);
  763.         EndEffect();
  764.     fi;
  765.     CallEffect(nil, GOLD_UP_ARROW_ID);
  766.     else
  767.     GSetPen(nil, pen);
  768.     GAMove(nil, 86, 45);
  769.     GRDraw(nil, 5, -5);
  770.     GRDraw(nil, 5, 5);
  771.     GRMove(nil, -5, -5);
  772.     GRDraw(nil, 0, 20);
  773.     fi;
  774. corp;
  775.  
  776. /*
  777.  * DrawDownArrow - draw the down arrow.
  778.  */
  779.  
  780. define t_graphics proc DrawDownArrow(int pen)void:
  781.  
  782.     if pen = C_GOLD then
  783.     if not KnowsEffect(nil, GOLD_DOWN_ARROW_ID) then
  784.         DefineEffect(nil, GOLD_DOWN_ARROW_ID);
  785.         GSetPen(nil, C_GOLD);
  786.         GAMove(nil, 64, 55);
  787.         GRDraw(nil, 5, 5);
  788.         GRDraw(nil, 5, -5);
  789.         GRMove(nil, -5, 5);
  790.         GRDraw(nil, 0, -20);
  791.         EndEffect();
  792.     fi;
  793.     CallEffect(nil, GOLD_DOWN_ARROW_ID);
  794.     else
  795.     GSetPen(nil, pen);
  796.     GAMove(nil, 64, 55);
  797.     GRDraw(nil, 5, 5);
  798.     GRDraw(nil, 5, -5);
  799.     GRMove(nil, -5, 5);
  800.     GRDraw(nil, 0, -20);
  801.     fi;
  802. corp;
  803.  
  804. /*
  805.  * DrawUpDown - draw up/down arrows for any of the auto graphics.
  806.  */
  807.  
  808. define t_graphics proc public DrawUpDown(thing here; list int exits)void:
  809.     int pen;
  810.  
  811.     pen := here@p_rEdgePen;
  812.     if pen = 0 or pen = here@p_rBackGroundPen or pen = here@p_rForeGroundPen
  813.     then
  814.     pen := C_GOLD;
  815.     fi;
  816.     if FindElement(exits, D_UP) ~= -1 then
  817.     DrawUpArrow(pen);
  818.     fi;
  819.     if FindElement(exits, D_DOWN) ~= -1 then
  820.     DrawDownArrow(pen);
  821.     fi;
  822. corp;
  823.  
  824. /*
  825.  * AutoRoads - autodraw a roads view.
  826.  */
  827.  
  828. define t_graphics proc public AutoRoads()void:
  829.     thing here;
  830.     int background, foreground;
  831.     list int exits;
  832.  
  833.     here := Here();
  834.     background := here@p_rBackGroundPen;
  835.     foreground := here@p_rForeGroundPen;
  836.     if background = 0 and foreground = 0 then
  837.     background := C_DARK_GREEN;
  838.     foreground := C_TAN;
  839.     fi;
  840.     exits := here@p_rExits;
  841.     GSetPen(nil, background);
  842.     GAMove(nil, 0, 0);
  843.     GRectangle(nil, 159, 99, true);
  844.     GSetPen(nil, foreground);
  845.     GAMove(nil, 80, 50);
  846.     GEllipse(nil, 15, 12, true);
  847.     if FindElement(exits, D_NORTH) ~= -1 then
  848.     GAMove(nil, 65, 0);
  849.     GRectangle(nil, 30, 50, true);
  850.     fi;
  851.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  852.     GPolygonStart(nil);
  853.     GAMove(nil, 159, 0);
  854.     GRDraw(nil, 0, 16);
  855.     GRDraw(nil, -70, 44);
  856.     GRDraw(nil, -16, -21);
  857.     GRDraw(nil, 62, -39);
  858.     GPolygonEnd(nil);
  859.     fi;
  860.     if FindElement(exits, D_EAST) ~= -1 then
  861.     GAMove(nil, 80, 38);
  862.     GRectangle(nil, 79, 24, true);
  863.     fi;
  864.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  865.     GPolygonStart(nil);
  866.     GAMove(nil, 159, 99);
  867.     GRDraw(nil, 0, -16);
  868.     GRDraw(nil, -71, -43);
  869.     GRDraw(nil, -16, 20);
  870.     GRDraw(nil, 63, 39);
  871.     GPolygonEnd(nil);
  872.     fi;
  873.     if FindElement(exits, D_SOUTH) ~= -1 then
  874.     GAMove(nil, 65, 50);
  875.     GRectangle(nil, 30, 49, true);
  876.     fi;
  877.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  878.     GPolygonStart(nil);
  879.     GAMove(nil, 0, 99);
  880.     GRDraw(nil, 24, 0);
  881.     GRDraw(nil, 67, -41);
  882.     GRDraw(nil, -17, -19);
  883.     GRDraw(nil, -74, 44);
  884.     GPolygonEnd(nil);
  885.     fi;
  886.     if FindElement(exits, D_WEST) ~= -1 then
  887.     GAMove(nil, 0, 38);
  888.     GRectangle(nil, 80, 24, true);
  889.     fi;
  890.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  891.     GPolygonStart(nil);
  892.     GAMove(nil, 0, 0);
  893.     GRDraw(nil, 24, 0);
  894.     GRDraw(nil, 64, 40);
  895.     GRDraw(nil, -16, 20);
  896.     GRDraw(nil, -72, -44);
  897.     GPolygonEnd(nil);
  898.     fi;
  899.     DrawUpDown(here, exits);
  900. corp;
  901.  
  902. /*
  903.  * AutoPaths - autodraw a paths view.
  904.  */
  905.  
  906. define t_graphics proc public AutoPaths()void:
  907.     thing here;
  908.     int background, foreground;
  909.     list int exits;
  910.  
  911.     here := Here();
  912.     background := here@p_rBackGroundPen;
  913.     foreground := here@p_rForeGroundPen;
  914.     if background = 0 and foreground = 0 then
  915.     background := C_FOREST_GREEN;
  916.     foreground := C_TAN;
  917.     fi;
  918.     exits := here@p_rExits;
  919.     GSetPen(nil, background);
  920.     GAMove(nil, 0, 0);
  921.     GRectangle(nil, 159, 99, true);
  922.     GSetPen(nil, foreground);
  923.     GAMove(nil, 80, 50);
  924.     GEllipse(nil, 5, 4, true);
  925.     if FindElement(exits, D_NORTH) ~= -1 then
  926.     GAMove(nil, 75, 0);
  927.     GRectangle(nil, 10, 50, true);
  928.     fi;
  929.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  930.     GPolygonStart(nil);
  931.     GAMove(nil, 159, 0);
  932.     GRDraw(nil, 0, 6);
  933.     GRDraw(nil, -76, 47);
  934.     GRDraw(nil, -6, -6);
  935.     GRDraw(nil, 74, -47);
  936.     GPolygonEnd(nil);
  937.     fi;
  938.     if FindElement(exits, D_EAST) ~= -1 then
  939.     GAMove(nil, 80, 46);
  940.     GRectangle(nil, 79, 8, true);
  941.     fi;
  942.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  943.     GPolygonStart(nil);
  944.     GAMove(nil, 159, 99);
  945.     GRDraw(nil, 0, -6);
  946.     GRDraw(nil, -76, -46);
  947.     GRDraw(nil, -6, 6);
  948.     GRDraw(nil, 74, 46);
  949.     GPolygonEnd(nil);
  950.     fi;
  951.     if FindElement(exits, D_SOUTH) ~= -1 then
  952.     GAMove(nil, 75, 50);
  953.     GRectangle(nil, 10, 49, true);
  954.     fi;
  955.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  956.     GPolygonStart(nil);
  957.     GAMove(nil, 0, 99);
  958.     GRDraw(nil, 8, 0);
  959.     GRDraw(nil, 75, -46);
  960.     GRDraw(nil, -6, -6);
  961.     GRDraw(nil, -77, 46);
  962.     GPolygonEnd(nil);
  963.     fi;
  964.     if FindElement(exits, D_WEST) ~= -1 then
  965.     GAMove(nil, 0, 46);
  966.     GRectangle(nil, 80, 8, true);
  967.     fi;
  968.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  969.     GPolygonStart(nil);
  970.     GAMove(nil, 0, 0);
  971.     GRDraw(nil, 8, 0);
  972.     GRDraw(nil, 75, 47);
  973.     GRDraw(nil, -6, 6);
  974.     GRDraw(nil, -77, -47);
  975.     GPolygonEnd(nil);
  976.     fi;
  977.     DrawUpDown(here, exits);
  978. corp;
  979.  
  980. /*
  981.  * AutoTunnels - autodraw a tunnels view.
  982.  */
  983.  
  984. define t_graphics proc public AutoTunnels()void:
  985.     thing here;
  986.     int background, foreground;
  987.     list int exits;
  988.  
  989.     here := Here();
  990.     background := here@p_rBackGroundPen;
  991.     foreground := here@p_rForeGroundPen;
  992.     if background = 0 and foreground = 0 then
  993.     background := C_DARK_GREY;
  994.     foreground := C_LIGHT_GREY;
  995.     fi;
  996.     exits := here@p_rExits;
  997.     GSetPen(nil, background);
  998.     GAMove(nil, 0, 0);
  999.     GRectangle(nil, 159, 99, true);
  1000.     GSetPen(nil, foreground);
  1001.     GAMove(nil, 80, 50);
  1002.     GEllipse(nil, 14, 8, true);
  1003.     if FindElement(exits, D_NORTH) ~= -1 then
  1004.     GAMove(nil, 65, 0);
  1005.     GRectangle(nil, 29, 50, true);
  1006.     fi;
  1007.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  1008.     GPolygonStart(nil);
  1009.     GAMove(nil, 159, 0);
  1010.     GRDraw(nil, 0, 13);
  1011.     GRDraw(nil, -71, 44);
  1012.     GRDraw(nil, -15, -15);
  1013.     GRDraw(nil, 69, -42);
  1014.     GPolygonEnd(nil);
  1015.     fi;
  1016.     if FindElement(exits, D_EAST) ~= -1 then
  1017.     GAMove(nil, 80, 42);
  1018.     GRectangle(nil, 79, 16, true);
  1019.     fi;
  1020.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  1021.     GPolygonStart(nil);
  1022.     GAMove(nil, 159, 99);
  1023.     GRDraw(nil, 0, -13);
  1024.     GRDraw(nil, -70, -42);
  1025.     GRDraw(nil, -16, 13);
  1026.     GRDraw(nil, 69, 42);
  1027.     GPolygonEnd(nil);
  1028.     fi;
  1029.     if FindElement(exits, D_SOUTH) ~= -1 then
  1030.     GAMove(nil, 65, 50);
  1031.     GRectangle(nil, 29, 49, true);
  1032.     fi;
  1033.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  1034.     GPolygonStart(nil);
  1035.     GAMove(nil, 0, 99);
  1036.     GRDraw(nil, 14, 0);
  1037.     GRDraw(nil, 74, -42);
  1038.     GRDraw(nil, -15, -14);
  1039.     GRDraw(nil, -73, 43);
  1040.     GPolygonEnd(nil);
  1041.     fi;
  1042.     if FindElement(exits, D_WEST) ~= -1 then
  1043.     GAMove(nil, 0, 42);
  1044.     GRectangle(nil, 80, 16, true);
  1045.     fi;
  1046.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  1047.     GPolygonStart(nil);
  1048.     GAMove(nil, 0, 0);
  1049.     GRDraw(nil, 14, 0);
  1050.     GRDraw(nil, 75, 44);
  1051.     GRDraw(nil, -17, 13);
  1052.     GRDraw(nil, -72, -44);
  1053.     GPolygonEnd(nil);
  1054.     fi;
  1055.     DrawUpDown(here, exits);
  1056. corp;
  1057.  
  1058. define tp_graphics GREYS_TUNNEL_CHAMBER_ID NextEffectId().
  1059.  
  1060. /*
  1061.  * DrawTunnelChamber - draw the non-exit part of a tunnel chamber.
  1062.  */
  1063.  
  1064. define t_graphics proc DrawTunnelChamber(int background, foreground)void:
  1065.  
  1066.     if background = C_DARK_GREY and foreground = C_LIGHT_GREY then
  1067.     if not KnowsEffect(nil, GREYS_TUNNEL_CHAMBER_ID) then
  1068.         DefineEffect(nil, GREYS_TUNNEL_CHAMBER_ID);
  1069.         GSetPen(nil, C_DARK_GREY);
  1070.         GAMove(nil, 0, 0);
  1071.         GRectangle(nil, 159, 99, true);
  1072.         GSetPen(nil, C_LIGHT_GREY);
  1073.         GPolygonStart(nil);
  1074.         GAMove(nil, 40, 20);
  1075.         GRDraw(nil, 79, 0);
  1076.         GRDraw(nil, 20, 15);
  1077.         GRDraw(nil, 0, 29);
  1078.         GRDraw(nil, -20, 15);
  1079.         GRDraw(nil, -79, 0);
  1080.         GRDraw(nil, -20, -15);
  1081.         GRDraw(nil, 0, -29);
  1082.         GPolygonEnd(nil);
  1083.         EndEffect();
  1084.     fi;
  1085.     CallEffect(nil, GREYS_TUNNEL_CHAMBER_ID);
  1086.     else
  1087.     GSetPen(nil, background);
  1088.     GAMove(nil, 0, 0);
  1089.     GRectangle(nil, 159, 99, true);
  1090.     GSetPen(nil, foreground);
  1091.     GPolygonStart(nil);
  1092.     GAMove(nil, 40, 20);
  1093.     GRDraw(nil, 79, 0);
  1094.     GRDraw(nil, 20, 15);
  1095.     GRDraw(nil, 0, 29);
  1096.     GRDraw(nil, -20, 15);
  1097.     GRDraw(nil, -79, 0);
  1098.     GRDraw(nil, -20, -15);
  1099.     GRDraw(nil, 0, -29);
  1100.     GPolygonEnd(nil);
  1101.     fi;
  1102. corp;
  1103.  
  1104. /*
  1105.  * AutoTunnelChamber - autodraw a large tunnel chamber.
  1106.  */
  1107.  
  1108. define t_graphics proc public AutoTunnelChamber()void:
  1109.     thing here;
  1110.     int background, foreground;
  1111.     list int exits;
  1112.  
  1113.     here := Here();
  1114.     background := here@p_rBackGroundPen;
  1115.     foreground := here@p_rForeGroundPen;
  1116.     if background = 0 and foreground = 0 then
  1117.     background := C_DARK_GREY;
  1118.     foreground := C_LIGHT_GREY;
  1119.     fi;
  1120.     exits := here@p_rExits;
  1121.     DrawTunnelChamber(background, foreground);
  1122.     if FindElement(exits, D_NORTH) ~= -1 then
  1123.     GAMove(nil, 65, 0);
  1124.     GRectangle(nil, 29, 20, true);
  1125.     fi;
  1126.     if FindElement(exits, D_SOUTH) ~= -1 then
  1127.     GAMove(nil, 65, 79);
  1128.     GRectangle(nil, 29, 20, true);
  1129.     fi;
  1130.     if FindElement(exits, D_EAST) ~= -1 then
  1131.     GAMove(nil, 139, 42);
  1132.     GRectangle(nil, 20, 15, true);
  1133.     fi;
  1134.     if FindElement(exits, D_WEST) ~= -1 then
  1135.     GAMove(nil, 0, 42);
  1136.     GRectangle(nil, 20, 15, true);
  1137.     fi;
  1138.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  1139.     GPolygonStart(nil);
  1140.     GAMove(nil, 119, 20);
  1141.     GRDraw(nil, 20, -20);
  1142.     GRDraw(nil, 20, 0);
  1143.     GRDraw(nil, 0, 15);
  1144.     GRDraw(nil, -20, 20);
  1145.     GPolygonEnd(nil);
  1146.     fi;
  1147.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  1148.     GPolygonStart(nil);
  1149.     GAMove(nil, 119, 79);
  1150.     GRDraw(nil, 20, 20);
  1151.     GRDraw(nil, 20, 0);
  1152.     GRDraw(nil, 0, -15);
  1153.     GRDraw(nil, -20, -20);
  1154.     GPolygonEnd(nil);
  1155.     fi;
  1156.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  1157.     GPolygonStart(nil);
  1158.     GAMove(nil, 40, 20);
  1159.     GRDraw(nil, -20, -20);
  1160.     GRDraw(nil, -20, 0);
  1161.     GRDraw(nil, 0, 15);
  1162.     GRDraw(nil, 20, 20);
  1163.     GPolygonEnd(nil);
  1164.     fi;
  1165.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  1166.     GPolygonStart(nil);
  1167.     GAMove(nil, 40, 79);
  1168.     GRDraw(nil, -20, 20);
  1169.     GRDraw(nil, -20, 0);
  1170.     GRDraw(nil, 0, -15);
  1171.     GRDraw(nil, 20, -20);
  1172.     GPolygonEnd(nil);
  1173.     fi;
  1174.     DrawUpDown(here, exits);
  1175. corp;
  1176.  
  1177. /*
  1178.  * AutoOpenSpace - autodraw an open space with edges.
  1179.  */
  1180.  
  1181. define t_graphics proc public AutoOpenSpace()void:
  1182.     thing here;
  1183.     int background, foreground;
  1184.     list int exits;
  1185.  
  1186.     here := Here();
  1187.     background := here@p_rBackGroundPen;
  1188.     foreground := here@p_rForeGroundPen;
  1189.     if background = 0 and foreground = 0 then
  1190.     foreground := C_DARK_GREEN;
  1191.     background := C_DARK_BROWN;
  1192.     fi;
  1193.     exits := here@p_rExits;
  1194.     GSetPen(nil, foreground);
  1195.     GAMove(nil, 0, 0);
  1196.     GRectangle(nil, 159, 99, true);
  1197.     GSetPen(nil, background);
  1198.     if FindElement(exits, D_NORTH) = -1 then
  1199.     GAMove(nil, 40, 0);
  1200.     GRectangle(nil, 79, 19, true);
  1201.     fi;
  1202.     if FindElement(exits, D_NORTHEAST) = -1 then
  1203.     GPolygonStart(nil);
  1204.     GAMove(nil, 119, 0);
  1205.     GRDraw(nil, 40, 0);
  1206.     GRDraw(nil, 0, 29);
  1207.     GRDraw(nil, -19, 0);
  1208.     GRDraw(nil, 0, -10);
  1209.     GRDraw(nil, -21, 0);
  1210.     GPolygonEnd(nil);
  1211.     fi;
  1212.     if FindElement(exits, D_EAST) = -1 then
  1213.     GAMove(nil, 140, 30);
  1214.     GRectangle(nil, 19, 39, true);
  1215.     fi;
  1216.     if FindElement(exits, D_SOUTHEAST) = -1 then
  1217.     GPolygonStart(nil);
  1218.     GAMove(nil, 159, 70);
  1219.     GRDraw(nil, 0, 29);
  1220.     GRDraw(nil, -39, 0);
  1221.     GRDraw(nil, 0, -19);
  1222.     GRDraw(nil, 20, 0);
  1223.     GRDraw(nil, 0, -10);
  1224.     GPolygonEnd(nil);
  1225.     fi;
  1226.     if FindElement(exits, D_SOUTH) = -1 then
  1227.     GAMove(nil, 40, 80);
  1228.     GRectangle(nil, 79, 19, true);
  1229.     fi;
  1230.     if FindElement(exits, D_SOUTHWEST) = -1 then
  1231.     GPolygonStart(nil);
  1232.     GAMove(nil, 0, 70);
  1233.     GRDraw(nil, 0, 29);
  1234.     GRDraw(nil, 39, 0);
  1235.     GRDraw(nil, 0, -19);
  1236.     GRDraw(nil, -20, 0);
  1237.     GRDraw(nil, 0, -10);
  1238.     GPolygonEnd(nil);
  1239.     fi;
  1240.     if FindElement(exits, D_WEST) = -1 then
  1241.     GAMove(nil, 0, 30);
  1242.     GRectangle(nil, 19, 39, true);
  1243.     fi;
  1244.     if FindElement(exits, D_NORTHWEST) = -1 then
  1245.     GPolygonStart(nil);
  1246.     GAMove(nil, 0, 29);
  1247.     GRDraw(nil, 0, -29);
  1248.     GRDraw(nil, 39, 0);
  1249.     GRDraw(nil, 0, 19);
  1250.     GRDraw(nil, -20, 0);
  1251.     GRDraw(nil, 0, 10);
  1252.     GPolygonEnd(nil);
  1253.     fi;
  1254.     DrawUpDown(here, exits);
  1255. corp;
  1256.  
  1257. /*
  1258.  * AutoOpenRoom - autodraw a room with corridors.
  1259.  */
  1260.  
  1261. define t_graphics proc public AutoOpenRoom()void:
  1262.     thing here;
  1263.     int background, foreground, edge;
  1264.     list int exits;
  1265.  
  1266.     here := Here();
  1267.     background := here@p_rBackGroundPen;
  1268.     foreground := here@p_rForeGroundPen;
  1269.     edge := here@p_rEdgePen;
  1270.     if background = 0 and foreground = 0 and edge = 0 then
  1271.     foreground := C_BLACK;
  1272.     background := C_MEDIUM_GREY;
  1273.     edge := C_TAN;
  1274.     fi;
  1275.     exits := here@p_rExits;
  1276.     GSetPen(nil, background);
  1277.     GAMove(nil, 0, 0);
  1278.     GRectangle(nil, 159, 99, true);
  1279.     GSetPen(nil, edge);
  1280.     GAMove(nil, 19, 19);
  1281.     GRectangle(nil, 121, 61, false);
  1282.     GSetPen(nil, foreground);
  1283.     GAMove(nil, 20, 20);
  1284.     GRectangle(nil, 119, 59, true);
  1285.     if FindElement(exits, D_NORTH) ~= -1 then
  1286.     GSetPen(nil, foreground);
  1287.     GAMove(nil, 66, 0);
  1288.     GRectangle(nil, 27, 19, true);
  1289.     GSetPen(nil, edge);
  1290.     GAMove(nil, 65, 0);
  1291.     GRDraw(nil, 0, 19);
  1292.     GAMove(nil, 94, 0);
  1293.     GRDraw(nil, 0, 19);
  1294.     fi;
  1295.     if FindElement(exits, D_SOUTH) ~= -1 then
  1296.     GSetPen(nil, foreground);
  1297.     GAMove(nil, 66, 79);
  1298.     GRectangle(nil, 27, 20, true);
  1299.     GSetPen(nil, edge);
  1300.     GAMove(nil, 65, 80);
  1301.     GRDraw(nil, 0, 19);
  1302.     GAMove(nil, 94, 80);
  1303.     GRDraw(nil, 0, 19);
  1304.     fi;
  1305.     if FindElement(exits, D_EAST) ~= -1 then
  1306.     GSetPen(nil, foreground);
  1307.     GAMove(nil, 140, 40);
  1308.     GRectangle(nil, 19, 19, true);
  1309.     GSetPen(nil, edge);
  1310.     GAMove(nil, 140, 40);
  1311.     GRDraw(nil, 19, 0);
  1312.     GAMove(nil, 140, 60);
  1313.     GRDraw(nil, 19, 0);
  1314.     fi;
  1315.     if FindElement(exits, D_WEST) ~= -1 then
  1316.     GSetPen(nil, foreground);
  1317.     GAMove(nil, 0, 40);
  1318.     GRectangle(nil, 19, 19, true);
  1319.     GSetPen(nil, edge);
  1320.     GAMove(nil, 0, 40);
  1321.     GRDraw(nil, 19, 0);
  1322.     GAMove(nil, 0, 60);
  1323.     GRDraw(nil, 19, 0);
  1324.     fi;
  1325.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  1326.     GSetPen(nil, foreground);
  1327.     GAMove(nil, 121, 0);
  1328.     GRectangle(nil, 38, 24, true);
  1329.     GSetPen(nil, edge);
  1330.     GAMove(nil, 120, 0);
  1331.     GRDraw(nil, 0, 19);
  1332.     GAMove(nil, 140, 25);
  1333.     GRDraw(nil, 19, 0);
  1334.     fi;
  1335.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  1336.     GSetPen(nil, foreground);
  1337.     GAMove(nil, 0, 0);
  1338.     GRectangle(nil, 39, 24, true);
  1339.     GSetPen(nil, edge);
  1340.     GAMove(nil, 39, 0);
  1341.     GRDraw(nil, 0, 19);
  1342.     GAMove(nil, 0, 25);
  1343.     GRDraw(nil, 19, 0);
  1344.     fi;
  1345.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  1346.     GSetPen(nil, foreground);
  1347.     GAMove(nil, 120, 74);
  1348.     GRectangle(nil, 39, 25, true);
  1349.     GSetPen(nil, edge);
  1350.     GAMove(nil, 120, 80);
  1351.     GRDraw(nil, 0, 19);
  1352.     GAMove(nil, 140, 74);
  1353.     GRDraw(nil, 19, 0);
  1354.     fi;
  1355.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  1356.     GSetPen(nil, foreground);
  1357.     GAMove(nil, 0, 74);
  1358.     GRectangle(nil, 40, 25, true);
  1359.     GSetPen(nil, edge);
  1360.     GAMove(nil, 40, 80);
  1361.     GRDraw(nil, 0, 19);
  1362.     GAMove(nil, 0, 74);
  1363.     GRDraw(nil, 19, 0);
  1364.     fi;
  1365.     DrawUpDown(here, exits);
  1366. corp;
  1367.  
  1368. /*
  1369.  * AutoHalls - a simple horizontal/vertical hallway set.
  1370.  */
  1371.  
  1372. define t_graphics proc public AutoHalls()void:
  1373.     thing here;
  1374.     list int exits;
  1375.     int background, foreground, edge;
  1376.  
  1377.     here := Here();
  1378.     background := here@p_rBackGroundPen;
  1379.     foreground := here@p_rForeGroundPen;
  1380.     edge := here@p_rEdgePen;
  1381.     if background = 0 and foreground = 0 and edge = 0 then
  1382.     foreground := C_BLACK;
  1383.     background := C_MEDIUM_GREY;
  1384.     edge := C_TAN;
  1385.     fi;
  1386.     exits := here@p_rExits;
  1387.     GSetPen(nil, background);
  1388.     GAMove(nil, 0, 0);
  1389.     GRectangle(nil, 159, 99, true);
  1390.     GSetPen(nil, edge);
  1391.     GAMove(nil, 65, 40);
  1392.     GRectangle(nil, 29, 20, false);
  1393.     GSetPen(nil, foreground);
  1394.     GAMove(nil, 66, 41);
  1395.     GRectangle(nil, 27, 18, true);
  1396.     if FindElement(exits, D_NORTH) ~= -1 then
  1397.     GSetPen(nil, edge);
  1398.     GAMove(nil, 65, 0);
  1399.     GRDraw(nil, 0, 39);
  1400.     GAMove(nil, 94, 0);
  1401.     GRDraw(nil, 0, 39);
  1402.     GSetPen(nil, foreground);
  1403.     GAMove(nil, 66, 0);
  1404.     GRectangle(nil, 27, 40, true);
  1405.     fi;
  1406.     if FindElement(exits, D_SOUTH) ~= -1 then
  1407.     GSetPen(nil, edge);
  1408.     GAMove(nil, 65, 61);
  1409.     GRDraw(nil, 0, 38);
  1410.     GAMove(nil, 94, 61);
  1411.     GRDraw(nil, 0, 38);
  1412.     GSetPen(nil, foreground);
  1413.     GAMove(nil, 66, 60);
  1414.     GRectangle(nil, 27, 39, true);
  1415.     fi;
  1416.     if FindElement(exits, D_EAST) ~= -1 then
  1417.     GSetPen(nil, edge);
  1418.     GAMove(nil, 95, 40);
  1419.     GRDraw(nil, 64, 0);
  1420.     GAMove(nil, 95, 60);
  1421.     GRDraw(nil, 64, 0);
  1422.     GSetPen(nil, foreground);
  1423.     GAMove(nil, 94, 41);
  1424.     GRectangle(nil, 65, 18, true);
  1425.     fi;
  1426.     if FindElement(exits, D_WEST) ~= -1 then
  1427.     GSetPen(nil, edge);
  1428.     GAMove(nil, 0, 40);
  1429.     GRDraw(nil, 64, 0);
  1430.     GAMove(nil, 0, 60);
  1431.     GRDraw(nil, 64, 0);
  1432.     GSetPen(nil, foreground);
  1433.     GAMove(nil, 0, 41);
  1434.     GRectangle(nil, 65, 18, true);
  1435.     fi;
  1436.     DrawUpDown(here, exits);
  1437. corp;
  1438.  
  1439. /*
  1440.  * AutoClosedRoom - autodraw a room with doors.
  1441.  */
  1442.  
  1443. define t_graphics proc public AutoClosedRoom()void:
  1444.     thing here;
  1445.     int background, foreground, edge, door;
  1446.     list int exits;
  1447.  
  1448.     here := Here();
  1449.     background := here@p_rBackGroundPen;
  1450.     foreground := here@p_rForeGroundPen;
  1451.     edge := here@p_rEdgePen;
  1452.     door := here@p_rDoorPen;
  1453.     if background = 0 and foreground = 0 and edge = 0 and door = 0 then
  1454.     background := C_MEDIUM_GREY;
  1455.     foreground := C_BLACK;
  1456.     edge := C_TAN;
  1457.     door := C_BROWN;
  1458.     fi;
  1459.     exits := here@p_rExits;
  1460.     GSetPen(nil, background);
  1461.     GAMove(nil, 0, 0);
  1462.     GRectangle(nil, 159, 99, true);
  1463.     GSetPen(nil, edge);
  1464.     GAMove(nil, 19, 19);
  1465.     GRectangle(nil, 121, 61, false);
  1466.     GSetPen(nil, foreground);
  1467.     GAMove(nil, 20, 20);
  1468.     GRectangle(nil, 119, 59, true);
  1469.     GSetPen(nil, door);
  1470.     if FindElement(exits, D_NORTH) ~= -1 then
  1471.     GAMove(nil, 75, 19);
  1472.     HorizontalDoor();
  1473.     fi;
  1474.     if FindElement(exits, D_SOUTH) ~= -1 then
  1475.     GAMove(nil, 75, 80);
  1476.     HorizontalDoor();
  1477.     fi;
  1478.     if FindElement(exits, D_EAST) ~= -1 then
  1479.     GAMove(nil, 140, 46);
  1480.     VerticalDoor();
  1481.     fi;
  1482.     if FindElement(exits, D_WEST) ~= -1 then
  1483.     GAMove(nil, 19, 46);
  1484.     VerticalDoor();
  1485.     fi;
  1486.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  1487.     GSetPen(nil, background);
  1488.     GPolygonStart(nil);
  1489.     GAMove(nil, 136, 19);
  1490.     GRDraw(nil, 4, 0);
  1491.     GRDraw(nil, 0, 4);
  1492.     GPolygonEnd(nil);
  1493.     GSetPen(nil, door);
  1494.     GAMove(nil, 136, 19);
  1495.     NorthEastDoor();
  1496.     fi;
  1497.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  1498.     GSetPen(nil, background);
  1499.     GPolygonStart(nil);
  1500.     GAMove(nil, 23, 19);
  1501.     GRDraw(nil, -4, 0);
  1502.     GRDraw(nil, 0, 4);
  1503.     GPolygonEnd(nil);
  1504.     GSetPen(nil, door);
  1505.     GAMove(nil, 23, 19);
  1506.     NorthWestDoor();
  1507.     fi;
  1508.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  1509.     GSetPen(nil, background);
  1510.     GPolygonStart(nil);
  1511.     GAMove(nil, 136, 80);
  1512.     GRDraw(nil, 4, 0);
  1513.     GRDraw(nil, 0, -4);
  1514.     GPolygonEnd(nil);
  1515.     GSetPen(nil, door);
  1516.     GAMove(nil, 140, 76);
  1517.     NorthWestDoor();
  1518.     fi;
  1519.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  1520.     GSetPen(nil, background);
  1521.     GPolygonStart(nil);
  1522.     GAMove(nil, 23, 80);
  1523.     GRDraw(nil, -4, 0);
  1524.     GRDraw(nil, 0, -4);
  1525.     GPolygonEnd(nil);
  1526.     GSetPen(nil, door);
  1527.     GAMove(nil, 19, 76);
  1528.     NorthEastDoor();
  1529.     fi;
  1530.     DrawUpDown(here, exits);
  1531. corp;
  1532.  
  1533. /* routines for the icon editor */
  1534.  
  1535. define tp_graphics EDIT_DONE_BUTTON    14.
  1536. define tp_graphics EDIT_CANCEL_BUTTON    15.
  1537. define tp_graphics EDIT_CLEAR_BUTTON    16.
  1538. define tp_graphics EDIT_REGION        2.
  1539.  
  1540. define tp_graphics p_pEditRestoreAction CreateActionProp().
  1541. define tp_graphics p_pEditIcon CreateIntListProp().
  1542. define tp_graphics p_pEISaveButtonAction CreateActionProp().
  1543. define tp_graphics p_pEISaveMouseAction CreateActionProp().
  1544. define tp_graphics p_pEISaveIdleAction CreateActionProp().
  1545. define tp_graphics p_pEIIsCursor CreateBoolProp().
  1546.  
  1547. define tp_graphics proc showIconPixel(int x, y)void:
  1548.     int n;
  1549.  
  1550.     n := y * 16 + x;
  1551.     if (Me()@p_pEditIcon[n >> 5] >> (31 - n & 0x1f)) & 1 ~= 0 then
  1552.     GSetPen(nil, C_WHITE);
  1553.     else
  1554.     GSetPen(nil, C_BLACK);
  1555.     fi;
  1556.     GAMove(nil, 30 + x * 6, 20 + y * 4);
  1557.     GRectangle(nil, 5, 3, true);
  1558.     GAMove(nil, 140 + x, 80 + y);
  1559.     GPixel(nil);
  1560. corp;
  1561.  
  1562. define tp_graphics proc showWholeIcon()void:
  1563.     int x, y;
  1564.  
  1565.     for x from 0 upto 15 do
  1566.     for y from 0 upto 15 do
  1567.         showIconPixel(x, y);
  1568.     od;
  1569.     od;
  1570. corp;
  1571.  
  1572. define tp_graphics proc iconEditMouseHandler(int n, x, y)void:
  1573.  
  1574.     if n = EDIT_REGION then
  1575.     x := x / 6;
  1576.     y := y / 4;
  1577.     n := y * 16 + x;
  1578.     Me()@p_pEditIcon[n >> 5] := Me()@p_pEditIcon[n >> 5] ><
  1579.         (1 << (31 - n & 0x1f));
  1580.     GUndrawIcons(nil);
  1581.     showIconPixel(x, y);
  1582.     GRedrawIcons(nil);
  1583.     fi;
  1584.     /* do not complain about other regions hit - MOVE_REGION is all around
  1585.        EDIT_REGION, and we just want to ignore hits there. */
  1586. corp;
  1587.  
  1588. define tp_graphics proc iconEditButtonHandler(int whichButton)void:
  1589.     thing me;
  1590.     action a;
  1591.     int i;
  1592.     list int icon;
  1593.  
  1594.     me := Me();
  1595.     if whichButton = EDIT_CLEAR_BUTTON then
  1596.     icon := Me()@p_pEditIcon;
  1597.     for i from 0 upto 7 do
  1598.         icon[i] := 0b0;
  1599.     od;
  1600.     GUndrawIcons(nil);
  1601.     showWholeIcon();
  1602.     GRedrawIcons(nil);
  1603.     else
  1604.     if whichButton = EDIT_DONE_BUTTON then
  1605.         if me@p_pEIIsCursor then
  1606.         me@p_pCursor := me@p_pEditIcon;
  1607.         SetCursorPattern(me@p_pCursor);
  1608.         else
  1609.         GNewIcon(me, me@p_pEditIcon);
  1610.         fi;
  1611.     fi;
  1612.     me -- p_pEIIsCursor;
  1613.     me -- p_pEditIcon;
  1614.     ignore SetCharacterButtonAction(me@p_pEISaveButtonAction);
  1615.     me -- p_pEISaveButtonAction;
  1616.     ignore SetCharacterMouseDownAction(me@p_pEISaveMouseAction);
  1617.     me -- p_pEISaveMouseAction;
  1618.     ignore SetCharacterIdleAction(me@p_pEISaveIdleAction);
  1619.     me -- p_pEISaveIdleAction;
  1620.     EraseButton(EDIT_DONE_BUTTON);
  1621.     EraseButton(EDIT_CANCEL_BUTTON);
  1622.     EraseButton(EDIT_CLEAR_BUTTON);
  1623.     EraseRegion(EDIT_REGION);
  1624.     GUndrawIcons(nil);
  1625.     GSetPen(nil, C_BLACK);
  1626.     GAMove(nil, 0, 0);
  1627.     GRectangle(nil, 159, 99, true);
  1628.     a := me@p_pEditRestoreAction;
  1629.     if a ~= nil then
  1630.         me -- p_pEditRestoreAction;
  1631.         call(a, void)();
  1632.     fi;
  1633.     GRedrawIcons(nil);
  1634.     fi;
  1635. corp;
  1636.  
  1637. define tp_graphics proc iconEditIdleHandler()void:
  1638.     thing me;
  1639.     action a;
  1640.  
  1641.     me := Me();
  1642.     me -- p_pEIIsCursor;
  1643.     me -- p_pEditIcon;
  1644.     ignore SetCharacterButtonAction(me@p_pEISaveButtonAction);
  1645.     me -- p_pEISaveButtonAction;
  1646.     ignore SetCharacterMouseDownAction(me@p_pEISaveMouseAction);
  1647.     me -- p_pEISaveMouseAction;
  1648.     a := me@p_pEISaveIdleAction;
  1649.     ignore SetCharacterIdleAction(a);
  1650.     me -- p_pEISaveIdleAction;
  1651.     me -- p_pEditRestoreAction;
  1652.     call(a, void)();
  1653. corp;
  1654.  
  1655. define tp_graphics proc copyIcon(list int old)list int:
  1656.     list int new;
  1657.     int i;
  1658.  
  1659.     new := CreateIntArray(8);
  1660.     for i from 0 upto 7 do
  1661.     new[i] := old[i];
  1662.     od;
  1663.     new
  1664. corp;
  1665.  
  1666. define tp_graphics EDIT_BOX_ID NextEffectId().
  1667.  
  1668. define tp_graphics proc startEdit()void:
  1669.     thing me;
  1670.     action a;
  1671.     int i;
  1672.  
  1673.     me := Me();
  1674.     a := SetCharacterButtonAction(iconEditButtonHandler);
  1675.     if a ~= nil then
  1676.     me@p_pEISaveButtonAction := a;
  1677.     fi;
  1678.     a := SetCharacterMouseDownAction(iconEditMouseHandler);
  1679.     if a ~= nil then
  1680.     me@p_pEISaveMouseAction := a;
  1681.     fi;
  1682.     a := SetCharacterIdleAction(iconEditIdleHandler);
  1683.     if a ~= nil then
  1684.     me@p_pEISaveIdleAction := a;
  1685.     fi;
  1686.     if not KnowsEffect(nil, EDIT_BOX_ID) then
  1687.     DefineEffect(nil, EDIT_BOX_ID);
  1688.     AddButton(164, 83, EDIT_DONE_BUTTON, "Done");
  1689.     AddButton(208, 83, EDIT_CANCEL_BUTTON, "Cancel");
  1690.     AddButton(268, 83, EDIT_CLEAR_BUTTON, "Clear");
  1691.     AddRegion(30, 20, 125, 83, EDIT_REGION);
  1692.     GUndrawIcons(nil);
  1693.     RemoveCursor();
  1694.     ClearGraphics();
  1695.     for i from 0 upto 3 do
  1696.         GSetPen(nil, i + 1);
  1697.         GAMove(nil, 26 + i, 16 + i);
  1698.         GRectangle(nil, 103 - 2 * i, 71 - 2 * i, false);
  1699.     od;
  1700.     EndEffect();
  1701.     fi;
  1702.     CallEffect(nil, EDIT_BOX_ID);
  1703.     showWholeIcon();
  1704.     GRedrawIcons(nil);
  1705. corp;
  1706.  
  1707. define t_graphics proc public StartIconEdit(action restoreAction)void:
  1708.     list int icon;
  1709.     thing me;
  1710.  
  1711.     me := Me();
  1712.     if restoreAction ~= nil then
  1713.     me@p_pEditRestoreAction := restoreAction;
  1714.     fi;
  1715.     icon := me@p_pIcon;
  1716.     if icon = nil then
  1717.     icon := CreateIntArray(8);
  1718.     /* fill in the default smiley-face icon */
  1719.     icon[0] := 0b00000000000000000000000000000000;
  1720.     icon[1] := 0b00000011110000000000110000110000;
  1721.     icon[2] := 0b00010000000010000001000000001000;
  1722.     icon[3] := 0b00100110011001000010000000000100;
  1723.     icon[4] := 0b00100000000001000010010000100100;
  1724.     icon[5] := 0b00010011110010000001000000001000;
  1725.     icon[6] := 0b00001100001100000000001111000000;
  1726.     icon[7] := 0b00000000000000000000000000000000;
  1727.     else
  1728.     /* lists are true database objects - we cannot do a 'cancel' if we
  1729.        just edit the original! */
  1730.     icon := copyIcon(icon);
  1731.     fi;
  1732.     me@p_pEditIcon := icon;
  1733.     me@p_pEIIsCursor := false;
  1734.     startEdit();
  1735. corp;
  1736.  
  1737. define t_graphics proc public StartCursorEdit(action restoreAction)void:
  1738.     thing me;
  1739.  
  1740.     me := Me();
  1741.     if restoreAction ~= nil then
  1742.     me@p_pEditRestoreAction := restoreAction;
  1743.     fi;
  1744.     me@p_pEditIcon := copyIcon(me@p_pCursor);
  1745.     me@p_pEIIsCursor := true;
  1746.     startEdit();
  1747. corp;
  1748.  
  1749. unuse tp_graphics
  1750.